home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Library / button.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  10KB  |  344 lines

  1. /*
  2.  * button.c  V3.1
  3.  *
  4.  * ToolManager button gadget class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Button class instance data */
  19. struct ButtonClassData {
  20.  struct TMMemberData *bcd_ExecObject;
  21.  struct TMMemberData *bcd_SoundObject;
  22. };
  23. #define TYPED_INST_DATA(cl, o) ((struct ButtonClassData *) INST_DATA((cl), (o)))
  24. #define GADGET(g)              ((struct Gadget *) (g))
  25.  
  26. /* Button class method: OM_NEW */
  27. #define DEBUGFUNCTION ButtonClassNew
  28. static ULONG ButtonClassNew(Class *cl, Object *obj, struct opSet *ops)
  29. {
  30.  BUTTONCLASS_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  31.                  PrintTagList(ops->ops_AttrList)))
  32.  
  33.  /* Call SuperClass */
  34.  if (obj = (Object *) DoSuperMethodA(cl, obj, (Msg) ops)) {
  35.   struct ButtonClassData *bcd   = TYPED_INST_DATA(cl, obj);
  36.   struct TMHandle        *tmh;
  37.   struct DockEntryChunk  *dec   = NULL;
  38.   const char             *text  = NULL;
  39.   Object                 *image = NULL;
  40.   Object                 *label;
  41.   BOOL                    error = FALSE;
  42.  
  43.   /* Initialize instance data */
  44.   bcd->bcd_ExecObject  = NULL;
  45.   bcd->bcd_SoundObject = NULL;
  46.  
  47.   /* Get TMHandle */
  48.   tmh = (struct TMHandle *) GetTagData(TMA_TMHandle, NULL, ops->ops_AttrList);
  49.  
  50.   /* Get dock entry data */
  51.   dec = (struct DockEntryChunk *) GetTagData(TMA_Entry, NULL,
  52.                                              ops->ops_AttrList);
  53.  
  54.   /* Attach objects */
  55.   if (dec) {
  56.    Object *o;
  57.  
  58.    /* Find Exec object */
  59.    if ((dec->dec_ExecObject != 0) &&
  60.        (o = FindTypedIDTMObject(tmh, dec->dec_ExecObject, TMOBJTYPE_EXEC)))
  61.  
  62.     /* Attach object */
  63.     bcd->bcd_ExecObject = (struct TMMemberData *) DoMethod(o, TMM_Attach, obj,
  64.                                                            TMV_Attach_Normal);
  65.  
  66.    /* Find Sound object */
  67.    if ((dec->dec_SoundObject != 0) &&
  68.        (o = FindTypedIDTMObject(tmh, dec->dec_SoundObject, TMOBJTYPE_SOUND)))
  69.  
  70.     /* Attach object */
  71.     bcd->bcd_SoundObject = (struct TMMemberData *) DoMethod(o, TMM_Attach,
  72.                                                             obj,
  73.                                                             TMV_Attach_Normal);
  74.   }
  75.  
  76.   /* Display image? */
  77.   if (GetTagData(TMA_Images, FALSE, ops->ops_AttrList)) {
  78.  
  79.    BUTTONCLASS_LOG(LOG0(Display Images))
  80.  
  81.    /* Find image object */
  82.    if ((dec->dec_ImageObject == 0) ||
  83.        ((image = FindTypedIDTMObject(tmh, dec->dec_ImageObject,
  84.                                      TMOBJTYPE_IMAGE)) == NULL))
  85.  
  86.     /* No image found -> error */
  87.     error = TRUE;
  88.   }
  89.  
  90.   /* Display text? */
  91.   if ((error == FALSE) && GetTagData(TMA_Text, FALSE, ops->ops_AttrList)) {
  92.  
  93.    BUTTONCLASS_LOG(LOG0(Display Text))
  94.  
  95.    /* Exec object valid? */
  96.    if (bcd->bcd_ExecObject) {
  97.  
  98.     /* Get name of exec object */
  99.     GetAttr(TMA_ObjectName, bcd->bcd_ExecObject->tmmd_Object, (ULONG *) &text);
  100.  
  101.    } else
  102.  
  103.     /* No text available -> error */
  104.     error = TRUE;
  105.   }
  106.  
  107.   BUTTONCLASS_LOG(LOG3(Attached, "Exec 0x%08lx Image 0x%08lx Sound 0x%08lx",
  108.                        bcd->bcd_ExecObject, image, bcd->bcd_SoundObject))
  109.  
  110.   /* No error? */
  111.   if (error == FALSE) {
  112.  
  113.    /* Create label image */
  114.    if (label = NewObject(ToolManagerEntryClass, NULL,
  115.                           TMA_String, text,
  116.                           TMA_Font,
  117.                            GetTagData(TMA_Font,   NULL, ops->ops_AttrList),
  118.                           TMA_Image,  image,
  119.                           TMA_Screen,
  120.                            GetTagData(TMA_Screen, NULL, ops->ops_AttrList),
  121.                           TAG_DONE)) {
  122.     Object *frame;
  123.  
  124.     BUTTONCLASS_LOG(LOG1(Label, "0x%08lx", label))
  125.  
  126.     /* Create frame image */
  127.     if (frame = NewObject(NULL, FRAMEICLASS, IA_FrameType, FRAME_BUTTON,
  128.                                              TAG_DONE)) {
  129.  
  130.      BUTTONCLASS_LOG(LOG1(Frame, "0x%08lx", frame))
  131.  
  132.      /* Set gadget images */
  133.      SetAttrs(obj, GA_LabelImage, label,
  134.                    GA_Image,      frame,
  135.                    TAG_DONE);
  136.  
  137.      /* Set gadget size */
  138.      SetAttrs(obj, GA_Width,  ((struct Image *) label)->Width,
  139.                    GA_Height, ((struct Image *) label)->Height,
  140.                    TAG_DONE);
  141.     } else {
  142.  
  143.      /* Couldn't create frame image, dispose label image */
  144.      DisposeObject(label);
  145.      error = TRUE;
  146.     }
  147.  
  148.    } else
  149.  
  150.     /* Couldn't create label image */
  151.     error = TRUE;
  152.   }
  153.  
  154.   /* Everything OK? */
  155.   if (error) {
  156.  
  157.    /* No, dispose object */
  158.    CoerceMethod(cl, obj, OM_DISPOSE);
  159.  
  160.    /* Clear object pointer */
  161.    obj = NULL;
  162.   }
  163.  }
  164.  
  165.  BUTTONCLASS_LOG(LOG1(Result, "0x%08lx", obj))
  166.  
  167.  return((ULONG) obj);
  168. }
  169.  
  170. /* Button class method: OM_DISPOSE */
  171. #undef  DEBUGFUNCTION
  172. #define DEBUGFUNCTION ButtonClassDispose
  173. static ULONG ButtonClassDispose(Class *cl, Object *obj, Msg msg)
  174. {
  175.  struct ButtonClassData *bcd = TYPED_INST_DATA(cl, obj);
  176.  
  177.  BUTTONCLASS_LOG(LOG0(Disposing))
  178.  
  179.  /* Dispose frame object */
  180.  if (GADGET(obj)->GadgetRender)
  181.   DisposeObject(GADGET(obj)->GadgetRender);
  182.  
  183.  /* Dispose label object */
  184.  if (GADGET(obj)->GadgetText)
  185.   DisposeObject(GADGET(obj)->GadgetText);
  186.  
  187.  /* Sound object attached? Release it */
  188.  if (bcd->bcd_SoundObject) DoMethod(bcd->bcd_SoundObject->tmmd_Object,
  189.                                     TMM_Detach, bcd->bcd_SoundObject);
  190.  
  191.  /* Exec object attached? Release it */
  192.  if (bcd->bcd_ExecObject) DoMethod(bcd->bcd_ExecObject->tmmd_Object,
  193.                                    TMM_Detach, bcd->bcd_ExecObject);
  194.  
  195.  /* Call SuperClass */
  196.  return(DoSuperMethodA(cl, obj, msg));
  197. }
  198.  
  199. /* Button class method: OM_SET */
  200. #undef  DEBUGFUNCTION
  201. #define DEBUGFUNCTION ButtonClassSet
  202. static ULONG ButtonClassSet(Class *cl, Object *obj, struct opSet *ops)
  203. {
  204.  struct TagItem *tstate = ops->ops_AttrList;
  205.  struct TagItem *ti;
  206.  
  207.  BUTTONCLASS_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  208.                   PrintTagList(ops->ops_AttrList)))
  209.  
  210.  /* Scan tag list */
  211.  while (ti = NextTagItem(&tstate))
  212.  
  213.   /* Which attribute shall be set? */
  214.   switch (ti->ti_Tag) {
  215.    case GA_Width:
  216.     /* Forward new width to Label image object */
  217.     SetAttrs(GADGET(obj)->GadgetText, IA_Width, ti->ti_Data);
  218.     break;
  219.  
  220.    case GA_Height:
  221.     /* Forward new height to Label image object */
  222.     SetAttrs(GADGET(obj)->GadgetText, IA_Height, ti->ti_Data);
  223.     break;
  224.   }
  225.  
  226.  /* Call SuperClass */
  227.  return(DoSuperMethodA(cl, obj, (Msg) ops));
  228. }
  229.  
  230. /* Button class method: TMM_Release */
  231. #undef  DEBUGFUNCTION
  232. #define DEBUGFUNCTION ButtonClassRelease
  233. static ULONG ButtonClassRelease(Class *cl, Object *obj,
  234.                                 struct TMP_Detach *tmpd)
  235. {
  236.  struct ButtonClassData *bcd = TYPED_INST_DATA(cl, obj);
  237.  
  238.  BUTTONCLASS_LOG(LOG2(Arguments, "Data 0x%08lx Object 0x%08lx",
  239.                       tmpd->tmpd_MemberData,
  240.                       tmpd->tmpd_MemberData->tmmd_Object))
  241.  
  242.  /* Exec or Sound object deleted? */
  243.  if (bcd->bcd_ExecObject == tmpd->tmpd_MemberData) {
  244.  
  245.   /* Tell image that the text is no longer valid */
  246.   DoMethod((Object *) GADGET(obj)->GadgetText, TMM_Release, NULL);
  247.  
  248.   bcd->bcd_ExecObject = NULL;
  249.  } else
  250.   bcd->bcd_SoundObject = NULL;
  251.  
  252.  /* Detach object */
  253.  DoMethod(tmpd->tmpd_MemberData->tmmd_Object, TMM_Detach,
  254.           tmpd->tmpd_MemberData);
  255.  
  256.  /* Return 1 to indicate that the method is implemented */
  257.  return(1);
  258. }
  259.  
  260. /* Button class method: TMM_Activate */
  261. #undef  DEBUGFUNCTION
  262. #define DEBUGFUNCTION ButtonClassActivate
  263. static ULONG ButtonClassActivate(Class *cl, Object *obj,
  264.                                  struct TMP_Activate *tmpa)
  265. {
  266.  struct ButtonClassData *bcd = TYPED_INST_DATA(cl, obj);
  267.  
  268.  ICONCLASS_LOG(LOG1(Data, "0x%08lx", tmpa->tmpa_Data))
  269.  
  270.  /* Activate sound object */
  271.  if (bcd->bcd_SoundObject) DoMethod(bcd->bcd_SoundObject->tmmd_Object,
  272.                                     TMM_Activate, NULL);
  273.  
  274.  /* Activate Exec object */
  275.  if (bcd->bcd_ExecObject) DoMethod(bcd->bcd_ExecObject->tmmd_Object,
  276.                                    TMM_Activate, tmpa->tmpa_Data);
  277.  
  278.  /* Return 1 to indicate that the method is implemented */
  279.  return(1);
  280. }
  281.  
  282. /* Button class dispatcher */
  283. #undef  DEBUGFUNCTION
  284. #define DEBUGFUNCTION ButtonClassDispatcher
  285. static __geta4 ULONG ButtonClassDispatcher(__A0 Class *cl, __A2 Object *obj,
  286.                                            __A1 Msg msg)
  287. {
  288.  ULONG rc;
  289.  
  290.  BUTTONCLASS_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  291.                       cl, obj, msg))
  292.  
  293.  switch(msg->MethodID) {
  294.   /* BOOPSI methods */
  295.   case OM_NEW:
  296.    rc = ButtonClassNew(cl, obj, (struct opSet *) msg);
  297.    break;
  298.  
  299.   case OM_DISPOSE:
  300.    rc = ButtonClassDispose(cl, obj, msg);
  301.    break;
  302.  
  303.   case OM_SET:
  304.    rc = ButtonClassSet(cl, obj, (struct opSet *) msg);
  305.    break;
  306.  
  307.   /* TM methods */
  308.   case TMM_Release:
  309.    rc = ButtonClassRelease(cl, obj, (struct TMP_Detach *) msg);
  310.    break;
  311.  
  312.   case TMM_Activate:
  313.    rc = ButtonClassActivate(cl, obj, (struct TMP_Activate *) msg);
  314.    break;
  315.  
  316.   /* Unknown method -> delegate to SuperClass */
  317.   default:
  318.    rc = DoSuperMethodA(cl, obj, msg);
  319.    break;
  320.  }
  321.  
  322.  return(rc);
  323. }
  324.  
  325. /* Create base class */
  326. #undef  DEBUGFUNCTION
  327. #define DEBUGFUNCTION CreateButtonClass
  328. const Class *CreateButtonClass(void)
  329. {
  330.  Class *cl;
  331.  
  332.  /* Create class */
  333.  if (cl = MakeClass(NULL, FRBUTTONCLASS, NULL, sizeof(struct ButtonClassData),
  334.                     0))
  335.  
  336.   /* Set dispatcher */
  337.   cl->cl_Dispatcher.h_Entry = (ULONG (*)()) ButtonClassDispatcher;
  338.  
  339.  BUTTONCLASS_LOG(LOG1(Class, "0x%08lx", cl))
  340.  
  341.  /* Return pointer to class */
  342.  return(cl);
  343. }
  344.